package com.gucheng.aigc.service.impl;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gucheng.aigc.common.ErrorCode;
import com.gucheng.aigc.exception.BusinessException;
import com.gucheng.aigc.exception.ThrowUtils;
import com.gucheng.aigc.manager.RedisLimiterManager;
import com.gucheng.aigc.mapper.ImageMapper;
import com.gucheng.aigc.model.dto.image.ImageByAiRequest;
import com.gucheng.aigc.model.entity.Image;
import com.gucheng.aigc.model.entity.User;
import com.gucheng.aigc.model.vo.ImageResponse;
import com.gucheng.aigc.retry.ImageRetrying;
import com.gucheng.aigc.service.ImageService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* @author 28221
* @description 针对表【image(图片分析表)】的数据库操作Service实现
* @createDate 2024-07-31 22:21:35
*/
@Service
@Slf4j
public class ImageServiceImpl extends ServiceImpl<ImageMapper, Image>
        implements ImageService {


    @Resource
    private RedisLimiterManager redisLimiterManager;

    @Resource
    private ImageRetrying imageRetrying;


    @Override
    public ImageResponse generateImageByAi(ImageByAiRequest ImageByAiRequest, User loginUser) {
        String imageDescription = ImageByAiRequest.getImageDescription();
        String name = ImageByAiRequest.getName();
        String goal = ImageByAiRequest.getGoal();

        // 校验数据
        ThrowUtils.throwIf(StringUtils.isBlank(goal), ErrorCode.PARAMS_ERROR, "目标为空");
        ThrowUtils.throwIf(StringUtils.isNotBlank(name) && name.length() > 100, ErrorCode.PARAMS_ERROR, "名称过长");

        // 构建AI生成图片的提示信息
        String prompt = this.buildPrompt(goal, imageDescription);

        // 限流
        redisLimiterManager.doRateLimit("generateImageByAi+" + loginUser.getId());

        // 三次重试机会
        String result = imageRetrying.retryDoChart(prompt);
        if (result == null) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "图片生成错误");
        }
        // 解析结果获取图片URL
        String imageUrl = this. parseImageUrl(result);

        // 将结果插入数据库
        Image image = new Image();
        image.setName(name);
        image.setGoal(goal);
        image.setImageDescription(imageDescription);
        image.setImageurl(imageUrl);
        image.setUserId(loginUser.getId());
        image.setCreateTime(new Date());
        image.setUpdateTime(new Date());
        image.setIsDelete(0);
        boolean saveResult = this.save(image);
        ThrowUtils.throwIf(!saveResult, ErrorCode.SYSTEM_ERROR, "图片信息保存失败");

        // 封装返回结果
        ImageResponse imageResponse = new ImageResponse();
        imageResponse.setImageUrl(imageUrl);
        imageResponse.setImageId(image.getId());
        log.info("{}使用了AI图片生成功能", loginUser.getId());
        return imageResponse;
    }




    private String buildPrompt(String goal, String imageDescription) {
        // 使用StringBuilder来构建复杂的提示信息
        StringBuilder promptBuilder = new StringBuilder();

        // 添加目标，确保它是具体的和指导性的
        promptBuilder.append(goal);

        // 如果图片描述可用，则添加
        if (StringUtils.isNotBlank(imageDescription)) {
            promptBuilder.append(". ").append(imageDescription);
        }

        // 添加额外的指导性信息，如风格、色彩、视角等
        promptBuilder.append(" 图片应该是二次元风格的.");

        // 如果有特定的尺寸要求
        promptBuilder.append(" 所需的尺寸是1024x1024像素.");

        // 返回构建好的提示信息
        return promptBuilder.toString();
    }

    // 解析AI服务的响应，获取图片URL
    private String parseImageUrl(String response) {
        // 定义用于匹配完整URL的正则表达式
        String regex = "url=(https?://[\\S]+)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(response);

        // 尝试在响应字符串中查找匹配的URL
        if (matcher.find()) {
            // 找到URL后，从匹配结果中提取实际的URL字符串
            // 匹配结果包含"url="，所以需要从索引4开始截取
            // 这里使用Matcher.end()截取到URL的末尾
            return response.substring(matcher.start() + 4, matcher.end());
        } else {
            // 如果没有找到匹配的URL，则抛出异常
            throw new RuntimeException("在AI响应中没有找到有效的URL");
        }
    }

}





